package com.zhouyu.paydemo.unipay.qrcode.ZS.ATM;

import com.zhouyu.paydemo.unipay.qrcode.DemoBase;
import com.zhouyu.paydemo.unipay.sdk.LogUtil;
import com.zhouyu.paydemo.unipay.sdk.QrcService;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * 用途：取现操作通知（银联->收款方）<br>
 * 日期： 2017-06<br>
 * 声明：以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己需要，按照技术文档编写。该代码仅供参考，不提供编码，性能，规范性等方面的保障<br>
 */
@SuppressWarnings("serial")
@Slf4j
public class CashWithdrawalNotifySK extends HttpServlet{

	@Override
	public void init() throws ServletException {
		/**
		 * 请求银联接入地址，获取证书文件，证书路径等相关参数初始化到SDKConfig类中
		 * 在java main 方式运行时必须每次都执行加载
		 * 如果是在web应用开发里,这个方法可使用监听的方式写入缓存,无须在这出现
		 */
		//这里已经将加载属性文件的方法挪到了web/AutoLoadServlet.java中
		//SDKConfig.getConfig().loadPropertiesFromSrc(); //从classpath加载acp_sdk.properties文件
		super.init();
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		resp.setCharacterEncoding(DemoBase.encoding);
		resp.setContentType("text/html;charset=" + DemoBase.encoding);

		log.info("接收取现操作通知开始");
		// 获取银联通知服务器发送的后台通知参数
		Map<String, String> valideData = getAllRequestParam(req);
		LogUtil.printRequestLog(valideData);

		//重要！验证签名前不要修改reqParam中的键值对的内容，否则会验签不过
		if (!QrcService.validate(valideData, DemoBase.encoding)) {
			log.info("验证签名结果[失败].");
			//验签失败，需解决验签问题
			
		} else {
			log.info("验证签名结果[成功].");
			//【注：验签成功后才应该编写处理逻辑】
			//判断respCode=00 和其他应答码并处理对应逻辑
			//
			//

			String reqType =valideData.get("reqType"); //获取附加处理请求的数据，其他字段也可用类似方式获取
			String version =valideData.get("version");
			//获取其他请求域....
			
			Map<String,String> respMap = new HashMap<String,String>();
			respMap.put("reqType", reqType);
			respMap.put("version", version);
			respMap.put("respCode", "00");
			respMap.put("respMsg", "成功");
			Map<String, String> rspData = QrcService.sign(respMap,DemoBase.encoding);
			resp.getWriter().write(getRequestParamString(rspData));
		}
		log.info("接收取现操作通知结束");
		
	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
			IOException {
		this.doPost(req, resp);
	}

	/**
	 * 获取请求参数中所有的信息
	 * 
	 * @param request
	 * @return
	 */
	public static Map<String, String> getAllRequestParam(final HttpServletRequest request) {
		Map<String, String> res = new HashMap<String, String>();
		Enumeration<?> temp = request.getParameterNames();
		if (null != temp) {
			while (temp.hasMoreElements()) {
				String en = (String) temp.nextElement();
				String value = request.getParameter(en);
				res.put(en, value);
				//在报文上送时，如果字段的值为空，则不上送<下面的处理为在获取所有参数数据时，判断若值为空，则删除这个字段>
				//System.out.println("ServletUtil类247行  temp数据的键=="+en+"     值==="+value);
				if (null == res.get(en) || "".equals(res.get(en))) {
					res.remove(en);
				}
			}
		}
		return res;
	}
	
	/**
	 * 将Map存储的对象，转换为key=value&key=value的字符(通知返回报文不做url编码)
	 *
	 * @param requestParam
	 * @param coder
	 * @return
	 */
	private static String getRequestParamString(Map<String, String> respParam) {

		StringBuffer sf = new StringBuffer("");
		String rspstr = "";
		if (null != respParam && 0 != respParam.size()) {
			for (Entry<String, String> en : respParam.entrySet()) {
				sf.append(en.getKey()
						+ "="
						+ (null == en.getValue() || "".equals(en.getValue()) ? "" : en.getValue()) + "&");
			}
			rspstr = sf.substring(0, sf.length() - 1);
		}
		log.info("Resp Message:[" + rspstr + "]");
		return rspstr;
	}
	
}
